home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / mtools.lha / mtools-2.0.7 / mdir.c < prev    next >
C/C++ Source or Header  |  1992-09-10  |  7KB  |  305 lines

  1. /*
  2.  * Display an MSDOS directory
  3.  *
  4.  * Emmet P. Gray            US Army, HQ III Corps & Fort Hood
  5.  * ...!uunet!uiucuxc!fthood!egray    Attn: AFZF-DE-ENV
  6.  * fthood!egray@uxc.cso.uiuc.edu    Directorate of Engineering & Housing
  7.  *                     Environmental Management Office
  8.  *                     Fort Hood, TX 76544-5057
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include "msdos.h"
  13. #include "patchlevel.h"
  14.  
  15. int fd = -1;                /* the file descriptor for the device */
  16. int dir_start;                /* starting sector for directory */
  17. int dir_len;                /* length of directory (in sectors) */
  18. int dir_entries;            /* number of directory entries */
  19. int clus_size;                /* cluster size (in sectors) */
  20. char *mcwd;                /* the Current Working Directory */
  21. int fat_error;                /* FAT error detected? */
  22.  
  23. static long getfree();
  24. static char *conv_date(), *conv_time();
  25.  
  26. main(argc, argv)
  27. int argc;
  28. char *argv[];
  29. {
  30.     int i, entry, files, fargn, wide, faked;
  31.     long size, blocks;
  32.     char *date, *time, last_drive, *fix_mcwd();
  33.     char *strncpy(), newpath[MAX_PATH], *get_name(), *get_path(), *pathname;
  34.     char *newfile, *filename, *unix_name(), volume[12], drive, *strpbrk();
  35.     char *strcpy(), *strcat(), newname[13], *strncat(), get_drive();
  36.     void exit();
  37.     struct directory *dir, *dir_read();
  38.  
  39.     fargn = 1;
  40.     wide = 0;
  41.     files = 0;
  42.                     /* first argument */
  43.     if (argc > 1) {
  44.         if (!strcmp(argv[1], "-w")) {
  45.             wide = 1;
  46.             fargn = 2;
  47.         }
  48.         if (argv[1][0] == '-' && !wide) {
  49.             fprintf(stderr, "%s: illegal option -- %c\n", argv[0], argv[1][1]);
  50.             fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE);
  51.             fprintf(stderr, "Usage: %s: [-w] msdosdirectory\n", argv[0]);
  52.             fprintf(stderr, "       %s: [-w] msdosfile [msdosfiles...]\n", argv[0]);
  53.             exit(1);
  54.         }
  55.     }
  56.                     /* fake an argument */
  57.     faked = 0;
  58.     if (argc == fargn) {
  59.         faked++;
  60.         argc++;
  61.     }
  62.     last_drive = 'x';
  63.     mcwd = fix_mcwd();
  64.  
  65.     for (i = fargn; i < argc; i++) {
  66.         if (faked) {
  67.             drive = get_drive("");
  68.             filename = get_name("");
  69.             pathname = get_path("");
  70.         }
  71.         else {
  72.             drive = get_drive(argv[i]);
  73.             filename = get_name(argv[i]);
  74.             pathname = get_path(argv[i]);
  75.         }
  76.                     /* is this a new device? */
  77.         if (drive != last_drive) {
  78.             if (last_drive != 'x') {
  79.                 blocks = getfree() * MSECTOR_SIZE;
  80.                 if (!files)
  81.                     printf("File \"%s\" not found\n\n", newname);
  82.                 else
  83.                     printf("     %3d File(s)     %6ld bytes free\n\n", files, blocks);
  84.             }
  85.             if (init(drive, 0)) {
  86.                 fprintf(stderr, "%s: Cannot initialize '%c:'\n", argv[0], drive);
  87.                 continue;
  88.             }
  89.             last_drive = drive;
  90.             files = 0;
  91.                     /* find the volume label */
  92.             volume[0] = '\0';
  93.             for (entry = 0; entry < dir_entries; entry++) {
  94.                 dir = dir_read(entry);
  95.  
  96.                     /* if empty */
  97.                 if (dir->name[0] == 0x0)
  98.                     break;
  99.  
  100.                     /* if erased */
  101.                 if (dir->name[0] == 0xe5)
  102.                     continue;
  103.  
  104.                     /* if not volume label */
  105.                 if (!(dir->attr & 0x08))
  106.                     continue;
  107.  
  108.                 strncpy(volume, (char *) dir->name, 8);
  109.                 volume[8] = '\0';
  110.                 strncat(volume, (char *) dir->ext, 3);
  111.                 volume[11] = '\0';
  112.                 break;
  113.             }
  114.             if (volume[0] == '\0')
  115.                 printf(" Volume in drive %c has no label\n", drive);
  116.             else
  117.                 printf(" Volume in drive %c is %s\n", drive, volume);
  118.         }
  119.  
  120.         /*
  121.          * Move to "first guess" subdirectory, so that is_dir() can
  122.          * search to see if filename is also a directory.
  123.          */
  124.         if (subdir(drive, pathname))
  125.             continue;
  126.  
  127.         /*
  128.          * Under MSDOS, wildcards that match directories don't
  129.          * display the contents of that directory.  So I guess I'll
  130.          * do that too.
  131.          */
  132.         if ((strpbrk(filename, "*[?") == NULL) && is_dir(filename)) {
  133.             strcpy(newpath, pathname);
  134.             if (newpath[strlen(newpath) -1] != '/')
  135.                 strcat(newpath, "/");
  136.             strcat(newpath, filename);
  137.  
  138.                     /* move to real subdirectory */
  139.             if (subdir(drive, newpath))
  140.                 continue;
  141.  
  142.             strcpy(newname, "*");
  143.         }
  144.         else {
  145.             strcpy(newpath, pathname);
  146.             strcpy(newname, filename);
  147.         }
  148.                     /* if no files, assume '*' */
  149.         if (*filename == '\0')
  150.             strcpy(newname, "*");
  151.  
  152.         printf(" Directory for %c:%s\n\n", drive, newpath);
  153.  
  154.         for (entry = 0; entry < dir_entries; entry++) {
  155.             dir = dir_read(entry);
  156.                     /* if empty */
  157.             if (dir->name[0] == 0x0)
  158.                 break;
  159.                     /* if erased */
  160.             if (dir->name[0] == 0xe5)
  161.                 continue;
  162.                     /* if a volume label */
  163.             if (dir->attr & 0x08)
  164.                 continue;
  165.  
  166.             newfile = unix_name(dir->name, dir->ext);
  167.             if (!match(newfile, newname))
  168.                 continue;
  169.  
  170.             files++;
  171.             if (wide && files != 1) {
  172.                 if (!((files - 1) % 5))
  173.                     putchar('\n');
  174.             }
  175.             date = conv_date(dir->date[1], dir->date[0]);
  176.             time = conv_time(dir->time[1], dir->time[0]);
  177.             size = dir->size[3] * 0x1000000L + dir->size[2] * 0x10000L + dir->size[1] * 0x100 + dir->size[0];
  178.                     /* is a subdirectory */
  179.             if (dir->attr & 0x10) {
  180.                 if (wide)
  181.                     printf("%-8.8s %-3.3s   ", dir->name, dir->ext);
  182.                 else
  183.                     printf("%-8.8s %-3.3s     <DIR>     %s  %s\n", dir->name, dir->ext, date, time);
  184.                 continue;
  185.             }
  186.             if (wide)
  187.                 printf("%-8.8s %-3.3s   ", dir->name, dir->ext);
  188.             else
  189.                 printf("%-8.8s %-3.3s    %8ld   %s  %s\n", dir->name, dir->ext, size, date, time);
  190.         }
  191.         if (argc > 2)
  192.             putchar('\n');
  193.     }
  194.     if (fd < 0)
  195.         exit(1);
  196.  
  197.     blocks = getfree() * MSECTOR_SIZE;
  198.     if (!files)
  199.         printf("File \"%s\" not found\n", newname);
  200.     else
  201.         printf("     %3d File(s)     %6ld bytes free\n", files, blocks);
  202.     close(fd);
  203.     exit(0);
  204. }
  205.  
  206. /*
  207.  * Get the amount of free space on the diskette
  208.  */
  209.  
  210. static long
  211. getfree()
  212. {
  213.     register unsigned int i;
  214.     long total;
  215.     extern unsigned int num_clus;
  216.     unsigned int fat_decode();
  217.  
  218.     total = 0L;
  219.     for (i = 2; i < num_clus + 2; i++) {
  220.                     /* if fat_decode returns zero */
  221.         if (!fat_decode(i))
  222.             total += clus_size;
  223.     }
  224.     return(total);
  225. }
  226.  
  227. /*
  228.  * Convert an MSDOS directory date stamp to ASCII
  229.  */
  230.  
  231. static char *
  232. conv_date(date_high, date_low)
  233. unsigned date_high, date_low;
  234. {
  235. /*
  236.  *        hi byte     |    low byte
  237.  *    |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
  238.  *      | | | | | | | | | | | | | | | | |
  239.  *      \   7 bits    /\4 bits/\ 5 bits /
  240.  *         year +80      month     day
  241.  */
  242.     static char ans[9];
  243.     unsigned char year, month_hi, month_low, day;
  244.  
  245.     year = (date_high >> 1) + 80;
  246.     month_hi = (date_high & 0x1) << 3;
  247.     month_low = date_low >> 5;
  248.     day = date_low & 0x1f;
  249.     sprintf(ans, "%2d-%02d-%02d", month_hi + month_low, day, year);
  250.     return(ans);
  251. }
  252.  
  253. /*
  254.  * Convert an MSDOS directory time stamp to ASCII.
  255.  */
  256.  
  257. static char *
  258. conv_time(time_high, time_low)
  259. unsigned time_high, time_low;
  260. {
  261. /*
  262.  *        hi byte     |    low byte
  263.  *    |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
  264.  *      | | | | | | | | | | | | | | | | |
  265.  *      \  5 bits /\  6 bits  /\ 5 bits /
  266.  *         hour      minutes     sec*2
  267.  */
  268.     static char ans[7];
  269.     char am_pm;
  270.     unsigned char hour, min_hi, min_low;
  271.  
  272.     hour = time_high >> 3;
  273.     am_pm = (hour >= 12) ? 'p' : 'a';
  274.     if (hour > 12)
  275.         hour = hour - 12;
  276.     if (hour == 0)
  277.         hour = 12;
  278.     min_hi = (time_high & 0x7) << 3;
  279.     min_low = time_low >> 5;
  280.     sprintf(ans, "%2d:%02d%c", hour, min_hi + min_low, am_pm);
  281.     return(ans);
  282. }
  283.  
  284. /*
  285.  * stubs for read-only programs
  286.  */
  287.  
  288. void
  289. disk_flush()
  290. {
  291.     extern int disk_dirty;
  292.  
  293.     disk_dirty = 0;
  294.     return;
  295. }
  296.  
  297. void
  298. dir_flush()
  299. {
  300.     extern int dir_dirty;
  301.  
  302.     dir_dirty = 0;
  303.     return;
  304. }
  305.